package com.jiezuo.auth.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.base.Joiner;
import com.jiezuo.auth.entity.*;
import com.jiezuo.auth.mapper.UserMapper;
import com.jiezuo.auth.service.LoginLogService;
import com.jiezuo.auth.service.LoginService;
import com.jiezuo.auth.service.PermissionService;
import com.jiezuo.auth.service.UserService;
import com.jiezuo.common.constant.SysConstant;
import com.jiezuo.common.enums.ResultEnums;
//import com.jiezuo.common.sign.SignatureGeneration;
import com.jiezuo.common.util.*;
import com.jiezuo.common.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@Slf4j
@Service
@Transactional
public class LoginServiceImpl implements LoginService {

    //生成jwt所需SigningKey
    @Value("${auth.secret-key}")
    private String secret_key;
    //用户登录有效期（单位：分钟）,默认30分钟
    @Value("${auth.login-time-limit}")
    private Integer login_time_limit = 30;
    //一个账号是否允许多个人同时登陆
    @Value("${auth.accounts-one-to-many}")
    private String accounts_one_to_many;
    //登录时是否使用验证码校验
    @Value("${auth.whether-use-captcha}")
    private String whether_use_captcha;
    //读取文件路径
    @Value("${file.file-read-path}")
    private String fileReadPath;
    //密码强度校验
    @Value("${weak.passwords}")
    private String weakPasswords;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PermissionService permissionService;

    @Autowired
    private UserService userService;

    @Autowired
    private LoginLogService loginLogService;

    @Override
    public Result login(User user, HttpServletRequest request) {
        User resultUser = null;

        //登录时是否使用验证码校验
        if (Boolean.valueOf(whether_use_captcha)) {
            String captcha = user.getCaptcha();//验证码
            // todo 非空校验start *********************
            if (!StringUtil.isNotEmpty(captcha)) {
                return new ResultUtil<>().setErrorMsg(ResultEnums.VERIFICATION_CODE_EMPTY.getCode(), ResultEnums.VERIFICATION_CODE_EMPTY.getReasonPhraseCN());//请输入验证码
            }
            if (!StringUtil.isNotEmpty(user.getKey())) {
                return new ResultUtil<>().setErrorMsg("500", "请输入初始化验证码获取的KEY值");
            }
            // todo 非空校验end *********************
            String code = redisTemplate.opsForValue().get(SysConstant.REDIS_CAPTCHA + user.getKey());
            if (!StringUtil.isNotEmpty(code)) {
                return new ResultUtil<>().setErrorMsg(ResultEnums.VERIFICATION_CODE_FAILURE.getCode(), ResultEnums.VERIFICATION_CODE_FAILURE.getReasonPhraseCN());//验证码失效，请刷新后重试
            } else if (!captcha.toLowerCase().equals(code.toLowerCase())) {
                return new ResultUtil<>().setErrorMsg(ResultEnums.VERIFICATION_CODE_ERROR.getCode(), ResultEnums.VERIFICATION_CODE_ERROR.getReasonPhraseCN());//验证码错误
            }
        }
        /********************2021-08-17 LDF 微信openId登录 start****************************/
        if (StringUtil.isNotEmpty(user.getOpen_id())) {
            QueryWrapper<User> userQuery = new QueryWrapper<>();
            userQuery.eq("open_id", user.getOpen_id());
            resultUser = userService.getOne(userQuery);
        } else {
            try {
                // 支持 用户名+姓名 登陆
                //resultUser = userMapper.getUserByUserName(user.getUser_name());
                resultUser = userMapper.getUserByUserNameOrRealName(user.getUser_name());
            } catch (Exception e) {
                log.info("查询出错: {}", e);
                e.printStackTrace();
                return new ResultUtil<>().setErrorMsg(ResultEnums.QUERY_FOR_USER_INFORMATION_EXCEPTIONS.getCode(), ResultEnums.QUERY_FOR_USER_INFORMATION_EXCEPTIONS.getReasonPhraseCN());//查询用户信息异常
            }
        }
        /********************2021-08-17 LDF 微信openId登录 end****************************/

        if (resultUser == null) {
            return new ResultUtil<>().setErrorMsg(ResultEnums.THE_USER_DOES_NOT_EXIST.getCode(), ResultEnums.THE_USER_DOES_NOT_EXIST.getReasonPhraseCN());//用户不存在，请联系管理添加
        }
        //状态：0正常，1禁用
        if (!"0".equals(resultUser.getStatus())) {
            return new ResultUtil<>().setErrorMsg(ResultEnums.USER_HAS_BEEN_DISABLED.getCode(), ResultEnums.USER_HAS_BEEN_DISABLED.getReasonPhraseCN());//当前用户已被禁用，请联系管理员处理
        }

        //临时密码
        boolean isTemporaryPassword = SysConstant.TEMPORARY_PASSWORD_PREFIX.equals(user.getPassword().subSequence(0, 3));
        if (isTemporaryPassword) {
            // 获取临时密码
            String temporaryPassword = redisTemplate.opsForValue().get(SysConstant.REDIS_TEMPORARY_PASSWORD + resultUser.getUser_code());
            if (!user.getPassword().equals(temporaryPassword)) {
                //临时密码错误或已失效
                return new ResultUtil<>().setErrorMsg(ResultEnums.TEMPORARY_PASSWORD_ERROR.getCode(), ResultEnums.TEMPORARY_PASSWORD_ERROR.getReasonPhraseCN());
            }
        } else if (!resultUser.getPassword().equals(MD5Util.MD5(user.getPassword() + resultUser.getSalt()))) {     //密码加密规则：数据库密码(password)+盐(salt),进行MD5加密
            return new ResultUtil<>().setErrorMsg(ResultEnums.LOGIN_PASSWORD_ERROR.getCode(), ResultEnums.LOGIN_PASSWORD_ERROR.getReasonPhraseCN());
        }
        /**
         * 查询用户权限 放入缓存
         */
        try {
            resultUser = userMapper.getUserByUserId(resultUser.getId());
        } catch (Exception e) {
            log.info("查询出错: {}", e);
            e.printStackTrace();
            return new ResultUtil<>().setErrorMsg(ResultEnums.QUERY_FOR_USER_INFORMATION_EXCEPTIONS.getCode(), ResultEnums.QUERY_FOR_USER_INFORMATION_EXCEPTIONS.getReasonPhraseCN());//查询用户信息异常
        }
        // todo.......(start).........用户当前企业，部门ancestors,正常情况下，只应该有一个，后期根据具体情况，在做修改


        //   todo >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 暂时注释掉。。。。。。。。。。。。
        List<Map<String, String>> ancestors = userMapper.findAncestorsByUserId(resultUser.getId());
        if (ancestors.size() > 0) {
            resultUser.setMain_enterprise(String.valueOf(ancestors.get(0).get("main_enterprise")));
            resultUser.setMain_dept(String.valueOf(ancestors.get(0).get("main_dept")));
        }
        // todo.......(end).........用户当前企业，部门ancestors,正常情况下，只应该有一个，后期根据具体情况，在做修改
        String accessToken = "";
        /**
         * token放入缓存
         */
        // 是否允许一个账号多个人同时登陆：如果token已经存在，则不再新增
        boolean accountsOneToMany = Boolean.valueOf(accounts_one_to_many);
        out:
        if (accountsOneToMany) {
            // 判断当前token是否有效，有效，不在创建
            String currentAccessToken = redisTemplate.opsForValue().get(SysConstant.REDIS_ACCESS_TOKEN + resultUser.getUser_name());
            if (currentAccessToken == null) {
                accessToken = JavaWebToken.createJWT(resultUser.getUser_name(), resultUser.getPassword(), secret_key, -1);
                redisTemplate.opsForValue().set(SysConstant.REDIS_ACCESS_TOKEN + resultUser.getUser_name(), accessToken, login_time_limit, TimeUnit.MINUTES);
                // 允许多人共用一个账户，每次登陆一个人，增加+1；不允许共用的情况下，设置为1【主要为处理退出问题】
                redisTemplate.opsForValue().increment(SysConstant.REDIS_ACCOUNT_LOGIN_NUM + resultUser.getUser_name());//递增
                break out;
            }
            Map<String, Object> stringObjectMap = null;
            try {
                stringObjectMap = JavaWebToken.parserJavaWebToken(currentAccessToken, secret_key);
            } catch (Exception e) {
                //清除token
                Boolean delToken = redisTemplate.delete(SysConstant.REDIS_ACCESS_TOKEN + resultUser.getUser_name());
                //清除角色
                Boolean delRoles = redisTemplate.delete(SysConstant.REDIS_ROLE + resultUser.getUser_name());
                //清除account_login_num
                Boolean numDelete = redisTemplate.delete(SysConstant.REDIS_ACCOUNT_LOGIN_NUM + resultUser.getUser_name());
                return new ResultUtil<>().setErrorMsg(ResultEnums.RESOLVE_TOKEN_FAILURE.getCode(), ResultEnums.RESOLVE_TOKEN_FAILURE.getReasonPhraseCN());
            }
            //token失效，重新生成
            if (stringObjectMap == null) {
                accessToken = JavaWebToken.createJWT(resultUser.getUser_name(), resultUser.getPassword(), secret_key, -1);
                redisTemplate.opsForValue().set(SysConstant.REDIS_ACCESS_TOKEN + resultUser.getUser_name(), accessToken, login_time_limit, TimeUnit.MINUTES);
                // 允许多人共用一个账户，每次登陆一个人，增加+1；不允许共用的情况下，设置为1【主要为处理退出问题】
                redisTemplate.opsForValue().increment(SysConstant.REDIS_ACCOUNT_LOGIN_NUM + resultUser.getUser_name());//递增
            } else {
                accessToken = currentAccessToken;
                // 允许多人共用一个账户，每次登陆一个人，增加+1；不允许共用的情况下，设置为1【主要为处理退出问题】
                redisTemplate.opsForValue().increment(SysConstant.REDIS_ACCOUNT_LOGIN_NUM + resultUser.getUser_name());//递增
            }
        } else {
            accessToken = JavaWebToken.createJWT(resultUser.getUser_name(), resultUser.getPassword(), secret_key, -1);
            redisTemplate.opsForValue().set(SysConstant.REDIS_ACCESS_TOKEN + resultUser.getUser_name(), accessToken, login_time_limit, TimeUnit.MINUTES);
            // 允许多人共用一个账户，每次登陆一个人，增加+1；不允许共用的情况下，设置为1【主要为处理退出问题】
            redisTemplate.opsForValue().increment(SysConstant.REDIS_ACCOUNT_LOGIN_NUM + resultUser.getUser_name());//递增
        }
        log.info("登录用户accessToken：{}", accessToken);
        /**
         * 角色放入缓存 TODO 向redis中缓存的数据太大了！！！
         */
        redisTemplate.opsForValue().set(SysConstant.REDIS_ROLE + resultUser.getUser_name(), JSON.toJSON(resultUser).toString(), login_time_limit, TimeUnit.MINUTES);
        //登录成功的返回值 》》》 map中的数据，供前端使用
        Map map = new HashMap<>();
        //  用户头像地址拼接
        resultUser.setAvatar(fileReadPath + resultUser.getAvatar());
        map.put("userInfo", resultUser);
        map.put("accessToken", accessToken);
        /*******************************查询用户资质分类放入缓存LDF2021-08-19 start ***********************************/
       /*  Result<String> result = quaClient.findUserQualification(resultUser.getMain_dept());
        if (!result.isSuccess()){
            throw new BusinessRuntimeException(result.getMessage());//调用失败，抛出异常
        }
        String  userQualificationJson=result.getResult();
        if (StringUtil.isNotEmpty(userQualificationJson)){
            redisTemplate.opsForValue().set(SysConstant.REDIS_QUALIFICATION + user.getUser_name(),userQualificationJson);
        } */
        /*******************************查询用户资质分类放入缓存LDF2021-08-19 end ***********************************/


        /*********************************************** 登陆日志(start) *********************************************/
        /******************** 获取IP以及区域 *******************/
//        String ipAddress = IpUtil.getIp(request);
//        log.error("IP ======================================== " + ipAddress);
//        CZIPAddressUtils ip = new CZIPAddressUtils();
//        /**
//         * 本机 ipv4(127.0.0.1)  ipv6(0:0:0:0:0:0:0:1)
//         * 局域网 192.168.*.*
//         * */
//        if (!ipAddress.equals("127.0.0.1") && !ipAddress.equals("0:0:0:0:0:0:0:1") && !ipAddress.contains("192.168.")) {
//            ip.init();
//            System.out.println("IP地址[" + ipAddress + "]获取到的区域信息:" + ip.getIPLocation(ipAddress).getCountry() + ", 获取到的城市:" + ip.getIPLocation(ipAddress).getCity() + ", 运营商:" + ip.getIPLocation(ipAddress).getArea());
//        }
//
//        /******************** 获取浏览器信息 *******************/
//        try {
//            //获取浏览器信息
//            String ua = request.getHeader("User-Agent");
//            //转成UserAgent对象
//            UserAgent userAgent = UserAgent.parseUserAgentString(ua);
//            //获取浏览器信息
//            Browser browser = userAgent.getBrowser();
//            //获取系统信息
//            OperatingSystem os = userAgent.getOperatingSystem();
//            //系统名称
//            String system = os.getName();
//            //浏览器名称
//            String browserName = browser.getName();
//            log.info("系统名称:" + system);
//            log.info("浏览器名称:" + browserName);
//            LoginLog loginLog = new LoginLog();
//            loginLog.setUsername(user.getUser_name());
//            loginLog.setIp(ipAddress);
//            /**
//             * 本机 ipv4(127.0.0.1)  ipv6(0:0:0:0:0:0:0:1)
//             * 局域网 192.168.*.*
//             * */
//            if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
//                loginLog.setArea("本机");
//                loginLog.setCity("本机");
//                loginLog.setOperator("本机");
//            } else if (ipAddress.contains("192.168.")) {
//                loginLog.setArea("内网");
//                loginLog.setCity("内网");
//                loginLog.setOperator("内网");
//            } else {
//                loginLog.setArea(ip.getIPLocation(ipAddress).getCountry());
//                loginLog.setCity(ip.getIPLocation(ipAddress).getCity());
//                loginLog.setOperator(ip.getIPLocation(ipAddress).getArea());
//            }
//            loginLog.setSystem(system);
//            loginLog.setBrowser(browserName);
//            loginLog.setLogin_time(new Date());
//            loginLogService.save(loginLog);
//        } catch (Exception e) {
//            log.error("输出登陆日志异常：{}", e);
//        }
        /*********************************************** 登陆日志(end) *********************************************/

        return new ResultUtil<>().setData(map, ResultEnums.LOG_IN_SUCCESSFULLY.getReasonPhraseCN());//登陆成功
    }

    @Override
    public Result logout(String user_name) {
        Boolean logout_success = false;
        // 是否允许一个账号多个人同时登陆：如果token已经存在，则不再新增
        boolean accountsOneToMany = Boolean.valueOf(accounts_one_to_many);
        if (accountsOneToMany) {
            String account_login_num = redisTemplate.opsForValue().get(SysConstant.REDIS_ACCOUNT_LOGIN_NUM + user_name);
            if (Integer.valueOf(account_login_num) <= 1) {//剩下最后一个人，清空token及其他信息
                //清除token
                Boolean delToken = redisTemplate.delete(SysConstant.REDIS_ACCESS_TOKEN + user_name);
                //清除角色
                Boolean delRoles = redisTemplate.delete(SysConstant.REDIS_ROLE + user_name);
                //清除account_login_num
                Boolean numDelete = redisTemplate.delete(SysConstant.REDIS_ACCOUNT_LOGIN_NUM + user_name);
                logout_success = delToken && delRoles && numDelete;
            } else {
                redisTemplate.opsForValue().decrement(SysConstant.REDIS_ACCOUNT_LOGIN_NUM + user_name);//递减
                logout_success = true;
            }
        } else {
            //清除token
            Boolean delToken = redisTemplate.delete(SysConstant.REDIS_ACCESS_TOKEN + user_name);
            //清除角色
            Boolean delRoles = redisTemplate.delete(SysConstant.REDIS_ROLE + user_name);
            //清除account_login_num
            Boolean numDelete = redisTemplate.delete(SysConstant.REDIS_ACCOUNT_LOGIN_NUM + user_name);
            //清除用户关联资质分类‘
            redisTemplate.delete(SysConstant.REDIS_QUALIFICATION + "_" + user_name);
            logout_success = delToken && delRoles && numDelete;
        }
        if (logout_success) {
            return new ResultUtil<String>().setSuccessMsg(ResultEnums.LOGOUT_SUCCESS.getReasonPhraseCN());//登出成功
        } else {
            return new ResultUtil<String>().setErrorMsg(ResultEnums.LOGOUT_FAILED.getCode(), ResultEnums.LOGOUT_FAILED.getReasonPhraseCN());//登出失败
        }
    }

    @Override
    public Result authentication(String accessToken, String uri) {
        Boolean notToken = StringUtils.isBlank(accessToken);
        /**
         * 参数token不存在 就重新登录
         */
        if (notToken) {
            return new ResultUtil<>().setErrorMsg(ResultEnums.NOT_LOGGED_IN.getCode(), ResultEnums.NOT_LOGGED_IN.getReasonPhraseCN());// 未登录，请重新登录
        }
        /**
         * 解析token并验证
         */
        Map<String, Object> checkMap = null;
        try {
            checkMap = JavaWebToken.parserJavaWebToken(accessToken, secret_key);
        } catch (Exception e) {
            return new ResultUtil<>().setErrorMsg(ResultEnums.TOKEN_EXCEPTION.getCode(), ResultEnums.TOKEN_EXCEPTION.getReasonPhraseCN());//TOKEN异常，请重新登录
        }
        if (checkMap == null) {
            return new ResultUtil<>().setErrorMsg(ResultEnums.RESOLVE_TOKEN_FAILURE.getCode(), ResultEnums.RESOLVE_TOKEN_FAILURE.getReasonPhraseCN());//解析TOKEN失败，请重新登录
        }
        //通过解析jwt,获取用户名
        Map<String, Object> stringObjectMap = JavaWebToken.parserJavaWebToken(accessToken, secret_key);
        String sub = stringObjectMap.get("sub").toString();
        JSONObject object = JSON.parseObject(sub);
        String user_name = object.get("user_name") + "";
        /**
         * 查看缓存中是否存在当前用户
         */
        String redisToken = redisTemplate.opsForValue().get(SysConstant.REDIS_ACCESS_TOKEN + user_name);
        String redisRole = redisTemplate.opsForValue().get(SysConstant.REDIS_ROLE + user_name);
        //判断当前前端的token与redis中的token是否一致，不一致说明当前token已过期
        if (!accessToken.equals(redisToken)) {
            return new ResultUtil<>().setErrorMsg(ResultEnums.LOGIN_HAS_EXPIRED.getCode(), ResultEnums.LOGIN_HAS_EXPIRED.getReasonPhraseCN());//登录已失效，请重新登陆
        }
        /**
         * 如果缓存中不存在token 就重新登录
         */
        if (redisToken == null) {
            return new ResultUtil<>().setErrorMsg(ResultEnums.NOT_LOGGED_IN.getCode(), ResultEnums.NOT_LOGGED_IN.getReasonPhraseCN());//未登录，请重新登录
        }
        long t1 = SystemClock.now();

        /**
         * 过滤用户是否有相关权限
         */
        int count = 0;
        User user = JSONObject.parseObject(redisRole, User.class);
        if (user == null) {
            User user1 = userMapper.getUserByUserName(user_name);
            user = userMapper.getUserByUserId(user1.getId());
            redisTemplate.opsForValue().set(SysConstant.REDIS_ROLE + user_name, JSON.toJSON(user).toString(), login_time_limit, TimeUnit.MINUTES);
        }
        List<Map<String, String>> ancestors = userMapper.findAncestorsByUserId(user.getId());
        if (ancestors.size() > 0) {
            user.setMain_enterprise(String.valueOf(ancestors.get(0).get("main_enterprise")));
            user.setMain_dept(String.valueOf(ancestors.get(0).get("main_dept")));
        }

//        todo 测试环境注释掉
//        for (int i = 0; i < user.getRoles().size(); i++) {
//            for (int j = 0; j < user.getRoles().get(i).getMenus().size(); j++) {
//                String roleUrl = user.getRoles().get(i).getMenus().get(j).getComponent();
//                if (roleUrl.equals(uri)) {
//                    count++;
//                }
//            }
//        }
//        long t2 = SystemClock.now();
//        log.info(" 过滤用户是否有相关权限耗时：{}", (t2 - t1));
//        if (count == 0) {
//            return new ResultUtil<>().setErrorMsg(ResultEnums.USER_NO_PERMISSIONS.getCode(), ResultEnums.USER_NO_PERMISSIONS.getReasonPhraseCN());//该用户无权限
//        }
        Map<String, Object> map = new HashMap<>();
        //用户
        map.put("user", JSON.toJSONString(user));
        List<Role> roles = user.getRoles();
        String role_ids = "";
        if (roles != null) {
            role_ids = Joiner.on(",").join(roles.stream().map(Role::getId).collect(Collectors.toList()));
        }
        map.put("role_ids", role_ids);//角色ids
        List<Depart> departs = user.getDepts();
        String dept_ids = "";
        if (departs != null) {
            dept_ids = Joiner.on(",").join(departs.stream().map(Depart::getId).collect(Collectors.toList()));
        }
        map.put("dept_ids", dept_ids);//部门ids

        List<String> groupList = userMapper.findGroupIdsByUserId(user.getId());
        String group_ids = StringUtils.join(groupList, ",");
        map.put("group_ids", group_ids);//用于工作流

        List<String> flowGroupIds = userMapper.findFlowGroupIdsByUserId(user.getId());
        String flow_group_ids = StringUtils.join(flowGroupIds, ",");
        map.put("flow_group_ids", flow_group_ids);//用于工作流

        //鉴权通过，对Token自动续期
        tokenExtension(user_name);

        return new ResultUtil<>().setData(map, ResultEnums.AUTHORIZATION_SUCCESS.getReasonPhraseCN());//授权成功
    }

    // Token自动续期
    void tokenExtension(String username) {
        String accessToken = redisTemplate.opsForValue().get(SysConstant.REDIS_ACCESS_TOKEN + username);
        if (StringUtil.isNotEmpty(accessToken)) {
            redisTemplate.opsForValue().set(SysConstant.REDIS_ACCESS_TOKEN + username, accessToken, login_time_limit, TimeUnit.MINUTES);
        }
        String roles = redisTemplate.opsForValue().get(SysConstant.REDIS_ROLE + username);
        if (StringUtil.isNotEmpty(roles)) {
            redisTemplate.opsForValue().set(SysConstant.REDIS_ROLE + username, roles, login_time_limit, TimeUnit.MINUTES);
        }
    }

    /**
     * 功能描述: 三级菜单
     *
     * @throws
     * @author: 庞留杰
     * @return: Result<JSONArray>
     * @date: 2020/7/24 19:35
     */
    @Override
    public Result<JSONArray> threeLevelMenu(String user_id, String resource_type, String belongs) {
        List<Permission> permissions = userMapper.getPermissionByUserId(user_id, resource_type, null, belongs);
        permissions.forEach(it -> {
            if (StringUtil.isNotEmpty(it.getBackground_image()))
                it.setBg_image(fileReadPath + it.getBackground_image());
        });
        JSONArray jsonArray1 = new JSONArray();
        //顶级父ID
        String parent_id = "0";
        //一级
        List<Permission> oneLevel = getSubMenu(parent_id, permissions);
        if (oneLevel != null) {
            for (Permission permission1 : oneLevel) {
                JSONObject obj1 = new JSONObject();
                obj1.put("id", permission1.getId());
                obj1.put("component_name", permission1.getComponent_name());
                obj1.put("component", permission1.getComponent());
                obj1.put("path", permission1.getPath());
                obj1.put("resource_name", permission1.getResource_name());
                obj1.put("resource_icon", permission1.getResource_icon());
//                obj1.put("resource_method", permission1.getResource_method());
                obj1.put("parent_id", permission1.getParent_id());
                obj1.put("description", permission1.getDescription());
                obj1.put("resource_type", permission1.getResource_type());
                obj1.put("link_type", permission1.getLink_type());
                obj1.put("button_mark", permission1.getButton_mark());
                obj1.put("sort", permission1.getSort());
                obj1.put("level", "1");
                obj1.put("bg_image", permission1.getBg_image());
                obj1.put("belongs", permission1.getBelongs());//所属：0研究院，1九州
                //二级
                List<Permission> twoLevel = getSubMenu(permission1.getId(), permissions);
                JSONArray jsonArray2 = new JSONArray();
                if (twoLevel != null) {
                    for (Permission permission2 : twoLevel) {
                        JSONObject obj2 = new JSONObject();
                        obj2.put("id", permission2.getId());
                        obj2.put("component_name", permission2.getComponent_name());
                        obj2.put("component", permission2.getComponent());
                        obj2.put("path", permission2.getPath());
                        obj2.put("resource_name", permission2.getResource_name());
                        obj2.put("resource_icon", permission2.getResource_icon());
//                        obj2.put("resource_method", permission2.getResource_method());
                        obj2.put("parent_id", permission2.getParent_id());
                        obj2.put("description", permission2.getDescription());
                        obj2.put("resource_type", permission2.getResource_type());
                        obj2.put("link_type", permission2.getLink_type());
                        obj2.put("button_mark", permission2.getButton_mark());
                        obj2.put("sort", permission2.getSort());
                        obj2.put("level", "2");
                        obj2.put("bg_image", permission2.getBg_image());
                        //三级
                        List<Permission> threeLevel = getSubMenu(permission2.getId(), permissions);
                        JSONArray jsonArray3 = new JSONArray();
                        if (threeLevel != null) {
                            for (Permission permission3 : threeLevel) {
                                JSONObject obj3 = new JSONObject();
                                obj3.put("id", permission3.getId());
                                obj3.put("component_name", permission3.getComponent_name());
                                obj3.put("component", permission3.getComponent());
                                obj3.put("path", permission3.getPath());
                                obj3.put("resource_name", permission3.getResource_name());
                                obj3.put("resource_icon", permission3.getResource_icon());
//                                obj3.put("resource_method", permission3.getResource_method());
                                obj3.put("parent_id", permission3.getParent_id());
                                obj3.put("description", permission3.getDescription());
                                obj3.put("resource_type", permission3.getResource_type());
                                obj3.put("link_type", permission3.getLink_type());
                                obj3.put("button_mark", permission3.getButton_mark());
                                obj3.put("sort", permission3.getSort());
                                obj3.put("level", "3");
                                obj3.put("bg_image", permission3.getBg_image());
                                // 元数据
                                JSONObject meta = new JSONObject();
                                meta.put("resource_name", permission3.getResource_name());
                                obj3.put("meta", meta);

                                jsonArray3.add(obj3);
                            }
                        }

                        // 元数据
                        JSONObject meta = new JSONObject();
                        meta.put("resource_name", permission2.getResource_name());
                        obj2.put("meta", meta);

                        obj2.put("children", jsonArray3);
                        jsonArray2.add(obj2);
                    }
                }
                obj1.put("children", jsonArray2);

                // 元数据
                JSONObject meta = new JSONObject();
                meta.put("resource_name", permission1.getResource_name());
                obj1.put("meta", meta);

                jsonArray1.add(obj1);
            }
        }
        return new ResultUtil<JSONArray>().setData(jsonArray1);
    }

    /**
     * 功能描述: 无限级菜单
     *
     * @throws
     * @author: 庞留杰
     * @return: Result<JSONArray>
     * @date: 2020/7/24 19:35
     */
    @Override
    public JSONArray infiniteMenu(User user, String resource_type, String is_all, String belongs) {
        String user_id = user.getId();
        if ("true".equals(is_all)) {
            user_id = "";
        }
        List<Permission> permissions = new ArrayList<Permission>();
        if ("true".equals(is_all)) {
            QueryWrapper<Permission> queryWrapper = new QueryWrapper<Permission>();
            queryWrapper.eq("is_delete", "0");
            queryWrapper.eq("link_type", "0");//链接类型：0：菜单，1：按钮，2：外部链接
            queryWrapper.eq("belongs", belongs);//所属：0研究院，1九州
            queryWrapper.orderByAsc("sort");
            permissions = permissionService.list(queryWrapper);
        } else {
            permissions = userMapper.getPermissionByUserId(user_id, resource_type, null, belongs);
        }
        permissions.forEach(it -> {
            if (StringUtil.isNotEmpty(it.getBackground_image()))
                it.setBg_image(fileReadPath + it.getBackground_image());
        });
        //顶级父ID
        String parent_id = "0";
        //顶级数组
        JSONArray jsonArray = new JSONArray();
        int level = 0;
        loopMenu(parent_id, permissions, jsonArray, level);
        return jsonArray;
    }

    @Override
    public JSONArray initMenu(User user, String resource_type, String is_all) {
        JSONArray arr = new JSONArray();
        JSONArray jbjs = infiniteMenu(user, resource_type, is_all, "0");//基本建设
        JSONObject obj1 = new JSONObject();
        obj1.put("jbjs", jbjs);
        JSONArray jz = infiniteMenu(user, resource_type, is_all, "1");//九州
        JSONObject obj2 = new JSONObject();
        obj2.put("jz", jz);
        JSONArray dlhs = infiniteMenu(user, resource_type, is_all, "2");//独立核算
        JSONObject obj3 = new JSONObject();
        obj3.put("dlhs", dlhs);
        arr.add(obj1);
        arr.add(obj2);
        arr.add(obj3);
        return arr;
    }

    //递归获取菜单
    public void loopMenu(String parent_id, List<Permission> permissions, JSONArray jsonArray, int level) {
        List<Permission> subPermissions = getSubMenu(parent_id, permissions);
        if (subPermissions.size() > 0) {
            level++;
            for (Permission permission : subPermissions) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("id", permission.getId());
                jsonObject.put("component_name", permission.getComponent_name());
                jsonObject.put("component", permission.getComponent());
                jsonObject.put("path", permission.getPath());
                jsonObject.put("resource_name", permission.getResource_name());
                jsonObject.put("resource_icon", permission.getResource_icon());
//                jsonObject.put("resource_method", permission.getResource_method());
                jsonObject.put("parent_id", permission.getParent_id());
                jsonObject.put("description", permission.getDescription());
                jsonObject.put("resource_type", permission.getResource_type());
                jsonObject.put("link_type", permission.getLink_type());
                jsonObject.put("button_mark", permission.getButton_mark());
                jsonObject.put("sort", permission.getSort());
                jsonObject.put("is_show", permission.getIs_show());//是否显示，0是，1否
                jsonObject.put("level", level);
                jsonObject.put("bg_image", permission.getBg_image());
                jsonObject.put("belongs", permission.getBelongs());//所属：0研究院，1九州
                JSONArray array = new JSONArray();
                loopMenu(permission.getId(), permissions, array, level);
                jsonObject.put("children", array);

                // 元数据
                JSONObject meta = new JSONObject();
                meta.put("resource_name", permission.getResource_name());
                meta.put("form_id", permission.getForm_id());
                jsonObject.put("meta", meta);

                jsonArray.add(jsonObject);
            }
        }
    }

    // 获取子菜单
    public List<Permission> getSubMenu(String parent_id, List<Permission> permissions) {
        List<Permission> subs = new ArrayList<>();
        if (permissions != null) {
            for (Permission permission : permissions) {
                if (parent_id.equals(permission.getParent_id())) {
                    subs.add(permission);
                }
            }
        }
        return subs;
    }

//    @Override
//    public Result signature(HttpServletRequest request, String sign) throws Exception {
//        Map map = SignatureGeneration.parseSign(request, sign);
//        return new ResultUtil<>().setData(map);
//    }


}
